/**
 * Copyright 2010, Petascan Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.Ope
 */

package dremel.common;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenRewriteStream;
import org.antlr.runtime.tree.CommonTreeAdaptor;
import org.antlr.runtime.tree.TreeAdaptor;

/**
 * 
 * BQL Parser
 * 
 * 
 * @author camuelg
 */
public class DremelParser {
    public static AstNode parseBql(String bql) {
    	try{
		BqlLexer lexer = new BqlLexer(new ANTLRNoCaseStringStream(bql));
		TokenRewriteStream tokens = new TokenRewriteStream(lexer);
		BqlParser parser = new BqlParser(tokens);
		parser.setTreeAdaptor(adaptor);
		return (AstNode) parser.selectStatement().getTree();
        
    	}catch(Exception ex)
    	{
    		throw new RuntimeException("Parsing of the query "+bql + " has failed", ex);
    	}
	}

	static final TreeAdaptor adaptor = new CommonTreeAdaptor() {
		@Override
		public Object create(Token payload) {
			return new AstNode(payload);
		}
	};

	/**
	 * ANTLRNoCaseStringStream. //This class provides and implementation for a
	 * case insensitive token checker //for the lexical analysis part of antlr.
	 * By converting the token stream into //upper case at the time when lexical
	 * rules are checked, this class ensures that the //lexical rules need to
	 * just match the token with upper case letters as opposed to //combination
	 * of upper case and lower case characters. This is purely used for matching
	 * lexical //rules. The actual token text is stored in the same way as the
	 * user input without //actually converting it into an upper case. The token
	 * values are generated by the consume() //function of the super class
	 * ANTLRStringStream. The LA() function is the lookahead function //and is
	 * purely used for matching lexical rules. This also means that the grammar
	 * will only //accept capitalized tokens in case it is run from other tools
	 * like antlrworks which //do not have the ANTLRNoCaseStringStream
	 * implementation.
	 */
	static class ANTLRNoCaseStringStream extends ANTLRStringStream {

		public ANTLRNoCaseStringStream(String input) {
			super(input);
		}

		@Override
		public int LA(int i) {

			int returnChar = super.LA(i);
			if (returnChar == CharStream.EOF) {
				return returnChar;
			} else if (returnChar == 0) {
				return returnChar;
			}

			return Character.toUpperCase((char) returnChar);
		}
	}
}
